package com.woniuxy.patrol.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.common.utils.ResponseUtil;
import com.woniuxy.patrol.pojo.PatrolPoint;
import com.woniuxy.patrol.service.PatrolPointService;
import com.woniuxy.patrol.mapper.PatrolPointMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author 13162
* @description 针对表【wcm_patrol_point(巡更点表)】的数据库操作Service实现
* @createDate 2025-07-14 19:22:37
*/
@Service
public class PatrolPointServiceImpl extends ServiceImpl<PatrolPointMapper, PatrolPoint>
    implements PatrolPointService{


    @Resource
    private PatrolPointMapper patrolPointMapper;

    @Override
    public ResponseUtil getByCommunityId(Long communityId) {
        // 对应《巡更demo.docx》中按社区筛选巡更点位的功能
        List<PatrolPoint> points = patrolPointMapper.selectByCommunityId(communityId);
        return ResponseUtil.success(points);
    }

    @Override
    public ResponseUtil addPoint(PatrolPoint patrolPoint) {
        // 校验位置编号唯一性（对应《巡更demo.docx》中"判断是否重复"的要求）
        QueryWrapper<PatrolPoint> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("location_code", patrolPoint.getLocationCode())
                .eq("community_id", patrolPoint.getCommunityId())
                .eq("is_delete", 1);
        if (baseMapper.selectCount(queryWrapper) > 0) {
            return ResponseUtil.error("该位置编号已存在");
        }

        // 设置默认值
        patrolPoint.setStatus(1); // 默认为启用
        patrolPoint.setIsDelete(1); // 未删除
        patrolPoint.setCreateTime(new Date());
        patrolPoint.setUpdateTime(new Date());

        save(patrolPoint);
        return ResponseUtil.success("巡更点添加成功");
    }

    @Override
    public ResponseUtil updatePoint(PatrolPoint patrolPoint) {
        patrolPoint.setUpdateTime(new Date());
        updateById(patrolPoint);
        return ResponseUtil.success("巡更点更新成功");
    }

    @Override
    public ResponseUtil deletePoint(Long pointId) {
        // 逻辑删除（对应《巡更demo.docx》中删除功能的实现）
        PatrolPoint point = new PatrolPoint();
        point.setPointId(pointId);
        point.setIsDelete(0); // 标记为删除
        point.setUpdateTime(new Date());
        updateById(point);
        return ResponseUtil.success("巡更点删除成功");
    }

    @Override
    public ResponseUtil getByRouteId(Long routeId) {
        List<PatrolPoint> points = patrolPointMapper.selectByRouteId(routeId);
        return ResponseUtil.success(points);

    }
    // 新增：计算两点间距离（Haversine公式）
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径，单位：公里

        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);

        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return R * c * 1000; // 转换为米
    }

    @Override
    public Map<String, Object> validateLocation(Long pointId, Double userLatitude, Double userLongitude) {
        Map<String, Object> result = new HashMap<>();

        // 查询巡更点信息
        PatrolPoint point = getById(pointId);
        if (point == null || point.getIsDelete() == 0) {
            result.put("valid", false);
            result.put("message", "巡更点不存在");
            result.put("distance", -1);
            return result;
        }

        // 计算用户与巡更点的距离
        double distance = calculateDistance(
                point.getLatitude().doubleValue(),
                point.getLongitude().doubleValue(),
                userLatitude,
                userLongitude
        );

        // 判断是否在有效半径内 临时改为：允许1000米内签到（我的定位不准）
//        boolean isValid = distance <= point.getCheckinRadius();
        boolean isValid = distance <= (point.getCheckinRadius() + 950);
        result.put("valid", isValid);
        result.put("distance", Math.round(distance));
        result.put("checkinRadius", point.getCheckinRadius());

        return result;
    }
}




